package models

import (
	"errors"
	"strings"

	"coinsend/btc"
	"coinsend/eth"
	"coinsend/ltc"
	"coinsend/usdt"
	"coinsend/utils"

	"time"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
)

type Address struct {
	Id      int
	Uid     int
	Symbol  string
	Address string
	Nonce   int
	Created int
}

func init() {
	orm.RegisterModel(new(Address))
}

//添加币种地址信息
func ORMAddAddress(Symbol, Add string, Uid int) error {
	var address0 Address

	Type, err1 := ORMGetCoinType(Symbol)
	if err1 != nil {
		return errors.New("添加失败," + Symbol + "币种信息不存在" + err1.Error())
	}
	if Type == 10 {
		Symbol = "ETH"
		Add = strings.ToLower(Add)
	}
	//检查地址合法性

	if !utils.CheckAddress(Symbol, Add) {
		return errors.New("添加失败," + Symbol + "地址不合法")
	}

	o := orm.NewOrm()
	o.QueryTable("Address").Filter("Symbol", Symbol).Filter("Uid", Uid).One(&address0)
	if address0.Id != 0 {
		return errors.New("添加失败," + Symbol + "系列币种地址已存在")
	}
	var address1 Address
	o.QueryTable("Address").Filter("Address", Add).One(&address1)

	if address1.Uid != Uid && address1.Uid != 0 {
		return errors.New("添加失败," + "该地址已被他人使用,请更换地址后重试")
	}
	var Nonce int64
	var err11 error
	if Symbol == "ETH" {

		Nonce, err11 = eth.GetETHNonce(Add)
		if err11 != nil {
			return errors.New("添加失败,获取nonce失败,请确认地址的合法性" + err11.Error())
		}
	}
	address := new(Address)
	address.Uid = Uid
	address.Symbol = Symbol
	address.Address = Add
	address.Nonce = int(Nonce)
	address.Created = int(time.Now().Unix())
	_, err := o.Insert(address)
	if err != nil {
		return errors.New("添加失败,报错" + err.Error())
	}
	return nil
}

//删除币种地址信息
func ORMDelAddress(Id, Uid int) error {
	o := orm.NewOrm()
	address := new(Address)
	address.Id = Id
	o.Read(address)
	if address.Symbol != "" {
		if address.Uid == Uid {
			_, err := o.Delete(address)
			if err != nil {
				return errors.New("删除失败,报错" + err.Error())
			}
			return nil
		} else {
			return errors.New("删除失败,该地址为他人所有")
		}
	}
	return errors.New("删除失败,该地址不存在")
}

//获取用户币种地址
func GetAddressNonceByUidSymbol(Uid int, Symbol string) (string, int, error) {
	var address0 Address
	Type, err1 := ORMGetCoinType(Symbol)
	if err1 != nil {
		return "", 0, errors.New(Symbol + "币种信息不存在" + err1.Error())
	}
	if Type == 10 {
		Symbol = "ETH"
	}

	o := orm.NewOrm()
	o.QueryTable("Address").Filter("Uid", Uid).Filter("Symbol", Symbol).One(&address0)
	if address0.Id == 0 {
		return "", 0, errors.New("获取用户" + Symbol + "地址信息错误")
	}
	return address0.Address, address0.Nonce, nil
}

//用户地址nonce + 1
func AddOneForAddressNonce(Uid int, Symbol string) {
	var address0 Address
	Type, _ := ORMGetCoinType(Symbol)

	if Type == 10 {
		Symbol = "ETH"
	}
	o := orm.NewOrm()
	o.QueryTable("Address").Filter("Uid", Uid).Filter("Symbol", Symbol).One(&address0)
	address := new(Address)
	address.Id = address0.Id
	o.Read(address)
	address.Nonce = address.Nonce + 1
	o.Update(address)
}

type AddressAmount struct {
	Address string
	Symbol  string
	Amount  float64
	Id      int
}

//获取币种列表
func ORMListAddress(uid int) ([]AddressAmount, error) {
	var alladdress []Address
	var addressamount []AddressAmount
	o := orm.NewOrm()
	o.QueryTable("Address").Filter("Uid", uid).All(&alladdress)
	for _, v := range alladdress {
		var addressamount0 AddressAmount

		addressamount0.Address = v.Address
		addressamount0.Id = v.Id

		if v.Symbol == "ETH" {
			coin, _ := ORMListCoinByType(10)
			for _, val := range coin {

				addressamount0.Symbol = val.Symbol

				addressamount0.Amount = GetAddressAmountERC20(val.Symbol, v.Address)
				addressamount = append(addressamount, addressamount0)
				time.Sleep(time.Millisecond * 300)
			}
		} else if v.Symbol == "BTC" {
			addressamount0.Symbol = v.Symbol
			addressamount0.Amount = btc.Getaddressbalance(v.Address)
			addressamount = append(addressamount, addressamount0)
		} else if v.Symbol == "LTC" {
			addressamount0.Symbol = v.Symbol
			addressamount0.Amount = ltc.Getaddressbalance(v.Address)
			addressamount = append(addressamount, addressamount0)
		} else if v.Symbol == "USDT" {
			addressamount0.Symbol = v.Symbol
			addressamount0.Amount = usdt.Getaddressbalance(v.Address)
			addressamount = append(addressamount, addressamount0)
		} else {
			addressamount0.Symbol = v.Symbol
			addressamount0.Amount = 0
			addressamount = append(addressamount, addressamount0)

		}

	}

	return addressamount, nil

}

func GetAddressAmountERC20(Symbol, Address1 string) float64 {
	if Symbol == "ETH" {

		Amount, err11 := eth.GetETHBalance(Address1)
		if err11 != nil {
			beego.Debug(Symbol + "获取地址余额报错" + Address1 + err11.Error())
			return 0
		}
		return Amount
	} else {
		Contract, _, _ := ORMGetCoinFeeContract(Symbol)

		Amount, err11 := eth.GetETHTokenBalance(Address1, Contract)
		if err11 != nil {
			beego.Debug(Symbol + "获取地址余额报错" + Address1 + err11.Error())
			return 0
		}
		return Amount
	}
}

func GetAllAddressBySymbol(Symbol string) map[int]string {
	address := map[int]string{}

	var alladdress []Address
	o := orm.NewOrm()
	o.QueryTable("Address").Filter("Symbol", Symbol).All(&alladdress)

	for k, v := range alladdress {
		address[k] = v.Address
	}
	return address
}
